﻿#include"stdafx.h"
#ifdef LK_REFLECTION_
namespace LK
{
		const Reflection::PDomainNode ptr<Reflection::LibraryNode>::EmptyNode = Convert<Reflection::PDomainNode,ptr<Object>>::RefFrom(ptr<Object>());
		ptr<Reflection::LibraryNode>::ptr(weakptr<Reflection::TypeLibrary> const& library, Reflection::PDomainNode const&baseNode, ptr<String> const& name)
			:ptr<Object>(new Reflection::LibraryNode(library, baseNode, name)) {}
		ptr<String> ptr<Reflection::LibraryNode>::GetName() const
		{
			return Check()->GetName();
		}
		ptr<String> ptr<Reflection::LibraryNode>::GetFullName()const
		{
			if (GetBaseNode()==null)return GetName();
			return GetBaseNode().GetFullName() + GetLibrary().GetSeparatorRef() + GetName();
		}
		void ptr<Reflection::LibraryNode>::Clear()const { Check()->Clear(); }

		Reflection::PDomainNode ptr<Reflection::LibraryNode>::GetBaseNode() const{ return Check()->GetBaseNode(); }
		void ptr<Reflection::LibraryNode>::SetName(ptr<String> const &name) const{ Check()->SetName(name); }
		void ptr<Reflection::LibraryNode>::SetBaseNode(Reflection::PDomainNode const &node) const{ Check()->SetBaseNode(node); }
		weakptr<Reflection::TypeLibrary>  ptr<Reflection::LibraryNode>::GetLibrary() const
		{
			return Check()->GetLibrary();
		}
		void ptr<Reflection::LibraryNode>::SetLibrary(weakptr<Reflection::TypeLibrary> const&library)const { Check()->SetLibrary(library); }
	namespace Reflection
	{

		ptr<String> LibraryNode::ToString()const
		{
			return Name;
		}
		void LibraryNode::SetName(ptr<String> const&name)
		{
			if (Name != name)
			{
				if (BaseNode==null) { Name = name; return; }
				ptr<Collection::IArray<ptr<LibraryNode>>>& arr = ((PDomainNode&)BaseNode).GetInnerNodesRef();
				index_t i = arr==null ? -1 : arr->DichotomyIndexOf(this, &ptr<LibraryNode>::Compare);
				Name = name;
				if (i >= 0)//冒泡重排
				{
					while (i > 0 && ptr<LibraryNode>::Compare(arr[i - 1], arr[i]) > 0)Object::Swap(arr[i - 1], arr[i]);
					while (i + 1 < arr->size() && ptr<LibraryNode>::Compare(arr[i + 1], arr[i]) < 0)Object::Swap(arr[i + 1], arr[i]);
				}
				else ((PDomainNode&)BaseNode).AddInnerNode(this);
			}
		}
		void LibraryNode::SetBaseNode(PDomainNode const&node)
		{
			if (Object::ReferenceEqual(node, BaseNode))return;
			if (BaseNode!=null)//从原节点移除
			{
				ptr<Collection::IArray<ptr<LibraryNode>>>& arr = ((PDomainNode&)BaseNode).GetInnerNodesRef();
				index_t i = arr->DichotomyIndexOf(this, &ptr<LibraryNode>::Compare);
				if (i >= 0 && !arr[i]->Equals(this))
				{
					index_t k = 1;
					for (;;)
					{
						if (i - k >= 0 && arr[i - k]->Equals(this)) { i -= k; break; }
						if (i + k < arr->size() && arr[i + k]->Equals(this)) { i += k; break; }
						if (i - k < 0 && i + k >= arr->size()) { i = -1; break; }
					}
				}
				if (i >= 0)arr->RemoveAt(i);
			}
			BaseNode = node;
			if (node!=null&& ((PDomainNode&)node).GetInnerNodesRef()!=null&& ((PDomainNode&)node).GetInnerNodesRef()->DichotomyIndexOf(this, &ptr<LibraryNode>::Compare)<0)//插入合适的位置
				((PDomainNode&)node).GetInnerNodesRef()->DichotomyInsertAsc(this, &ptr<LibraryNode>::Compare);
		}
		LibraryNode::LibraryNode(weakptr<TypeLibrary> const & library, PDomainNode const & baseNode, ptr<String> const & name)
			:Name(name), BaseNode(baseNode), Library(){SetLibrary(library);}
		void LibraryNode::Clear()
		{
			Name=null;
			BaseNode=null;
			Library=null;
		}
		weakptr<TypeLibrary> LibraryNode::GetLibrary()const
		{
			return (weakptr<TypeLibrary> &)Library;
		}
		void LibraryNode::SetLibrary(ptr<TypeLibrary> const&library)
		{
			Library = library;
		}
		//获取名称
		ptr<String> LibraryNode::GetName()const { return Name; }
		PDomainNode LibraryNode::GetBaseNode()const { return (PDomainNode const&)BaseNode; }

		ptr<Collection::IArray<ptr<LibraryNode>>>& PDomainNode::GetInnerNodesRef()const { return Check()->InnerNodes; }
		ptr<LibraryNode> PDomainNode::GetInnerNodeByName(ptr<String> const & str)const { return Check()->GetInnerNodeByName(str); }
		void PDomainNode::RemoveInnerNode(ptr<LibraryNode> const & node) const
		{
			index_t i = GetInnerNodesRef()==null ? -1 : GetInnerNodesRef()->DichotomyIndexOf(node, &ptr<LibraryNode>::Compare);
			if (i >= 0)GetInnerNodesRef()->RemoveAt(i);
		}
		ptr<LibraryNode> PDomainNode::AddInnerNode(ptr<LibraryNode> node)const{
			return Check()->AddInnerNode(node);
		}
		PDomainNode::PDomainNode(weakptr<TypeLibrary> const& library, PDomainNode const&baseNode, ptr<String> const& name) :ptr<LibraryNode>(new DomainNode(library, baseNode, name)){}
		DomainNode::DomainNode(weakptr<TypeLibrary> const& library, PDomainNode const&baseNode, ptr<String> const& name) : LibraryNode(library, baseNode, name){}
		void DomainNode::Clear()
		{
			if (InnerNodes!=null)for (index_t i = 0; i < InnerNodes->size(); ++i)InnerNodes[i].Clear();
			InnerNodes=null;
			LibraryNode::Clear();
		}
		/**
		@brief 添加一个内部节点，并返回其引用*/
		ptr<LibraryNode> DomainNode::AddInnerNode(ptr<LibraryNode> node)
		{
			if (InnerNodes==null)InnerNodes = new LK::Collection::DefaultArray<ptr<LibraryNode>>();
			index_t i = InnerNodes->DichotomyIndexOf(node, &ptr<LibraryNode>::Compare);
			if (i >= 0)return InnerNodes[i];
			ptr<LibraryNode> r =InnerNodes[InnerNodes->DichotomyInsertAsc<ptr<LibraryNode> const&>(node, &ptr<LibraryNode>::Compare)];
			if (r.GetBaseNode()==null)r.SetBaseNode(this);//设置基命名空间
			r.SetLibrary(GetLibrary());//设置库
			return r;
		}
		/**
		@brief 获取当前节点下一个名为str的子节点，如果没有指定名称的子节点，则返回NULL*/
		ptr<LibraryNode> DomainNode::GetInnerNodeByName(ptr<String> const & str)const
		{
			if (InnerNodes==null)return ptr<LibraryNode>();
			index_t i = InnerNodes->DichotomyIndexOf(str, &ptr<LibraryNode>::StringCompare);
			return i < 0 ? ptr<LibraryNode>() : InnerNodes[i];
		}
	}
}
#endif
